﻿using System;
using System.Collections.Generic;

namespace Mathematics.Expressions
{
    public abstract class FunctionDefinition:MathExpression
    {
        private readonly ParameterDefinition[] _parameters;

        internal FunctionDefinition(string name,params ParameterDefinition[] parameters)
        {
            Name = name; 

            _parameters = parameters;
        }

        public string Name { get; private set; }
        

        public IEnumerable<ParameterDefinition> Parameters { get { return _parameters; } }
        

        public FunctionCall CreateCall(params MathExpression[] parameters)
        {
            var parameterList = new List<Parameter>();
            for (var i = 0; i < _parameters.Length;i++ )
            {
                var def = _parameters[i];
                MathExpression providedValue=null;
                if (i<parameters.Length)
                    providedValue = parameters[i];
                if (providedValue==null)
                    providedValue =def.DefaultValue;

                if (providedValue == null)
                    throw new InvalidOperationException("Parameter cannot be null");

                var parameter = new Parameter(def, providedValue);
                parameterList.Add(parameter);
            }

                return new FunctionCall(this, parameterList.ToArray());
        }

        internal abstract ExpressionValue Invoke(FunctionCall call);



        public override ExpressionValue Evaluate()
        {
            return ExpressionValue.Void;
        }

      
        protected internal override MathExpression Reduce(out bool didReduce)
        {
            throw new NotImplementedException();
        }
    }
}
